package com.cfp4cloud.cfp.knowledge.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cfp4cloud.cfp.admin.api.entity.SysUser;
import com.cfp4cloud.cfp.admin.api.feign.RemoteUserService;
import com.cfp4cloud.cfp.common.core.constant.SecurityConstants;
import com.cfp4cloud.cfp.common.core.constant.enums.YesNoEnum;
import com.cfp4cloud.cfp.common.core.util.R;
import com.cfp4cloud.cfp.common.security.util.SecurityUtils;
import com.cfp4cloud.cfp.knowledge.dto.AiDatasetEntityDTO;
import com.cfp4cloud.cfp.knowledge.entity.AiDatasetEntity;
import com.cfp4cloud.cfp.knowledge.entity.AiDatasetUserEntity;
import com.cfp4cloud.cfp.knowledge.mapper.AiDatasetMapper;
import com.cfp4cloud.cfp.knowledge.mapper.AiDatasetUserMapper;
import com.cfp4cloud.cfp.knowledge.service.AiDatasetService;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collection;
import java.util.List;
import java.util.Objects;

/**
 * AI知识库服务实现类
 * <p>
 * 管理知识库的创建、查询和权限控制 支持公开和私有知识库的访问管理 提供用户级别的可见性设置
 *
 * @author pig
 * @date 2024-03-14 13:39:21
 */
@Service
@RequiredArgsConstructor
public class AiDatasetServiceImpl extends ServiceImpl<AiDatasetMapper, AiDatasetEntity> implements AiDatasetService {

	/**
	 * 远程用户服务 用于查询用户信息
	 */
	private final RemoteUserService remoteUserService;

	/**
	 * 知识库用户关联数据访问层
	 */
	private final AiDatasetUserMapper aiDatasetUserMapper;

	/**
	 * 分页查询知识库列表
	 * <p>
	 * 支持按条件筛选和分页
	 * @param page 分页参数
	 * @return 知识库分页数据
	 */
	@Override
	public Page<AiDatasetEntity> getAiDatasetPage(Page<AiDatasetEntity> page) {
		return baseMapper.getAiDatasetPage(page);
	}

	/**
	 * 根据ID查询公开知识库
	 * <p>
	 * 仅返回公开的知识库信息 私有知识库将返回访问失败
	 * @param datasetId 知识库ID
	 * @return 知识库信息或错误提示
	 */
	@Override
	public R getDatasetById(Long datasetId) {
		if (datasetId == null) {
			return R.failed("目标知识库ID不能为空");
		}

		AiDatasetEntity dataset = baseMapper.selectById(datasetId);
		if (Objects.isNull(dataset) || YesNoEnum.NO.getCode().equals(dataset.getPublicFlag())) {
			return R.failed(StrUtil.format("私有知识库，无法查看"));
		}

		return R.ok(dataset);
	}

	/**
	 * 创建新知识库
	 * <p>
	 * 自动生成集合名称 支持设置可见用户列表 使用事务确保数据一致性
	 * @param aiDatasetEntityDTO 知识库创建参数
	 * @return 创建结果
	 * @throws Exception 创建失败时抛出
	 */
	@SneakyThrows
	@Override
	@Transactional(rollbackFor = Exception.class)
	public R saveDataset(AiDatasetEntityDTO aiDatasetEntityDTO) {
		AiDatasetEntity aiDataset = new AiDatasetEntity();
		BeanUtils.copyProperties(aiDatasetEntityDTO, aiDataset);
		this.save(aiDataset);
		aiDataset.setCollectionName(SecurityConstants.CFP_PREFIX + aiDataset.getId());
		baseMapper.updateById(aiDataset);

		// 设置知识库的可见用户
		return setDatasetVisible(aiDatasetEntityDTO, aiDataset);
	}

	/**
	 * 更新知识库信息
	 * <p>
	 * 更新基本信息和可见用户列表
	 * @param aiDatasetEntityDTO 知识库更新参数
	 * @return 更新结果
	 */
	@Override
	public R updateDataset(AiDatasetEntityDTO aiDatasetEntityDTO) {
		AiDatasetEntity aiDataset = new AiDatasetEntity();
		BeanUtils.copyProperties(aiDatasetEntityDTO, aiDataset);
		this.updateById(aiDataset);

		// 设置知识库的可见用户
		return setDatasetVisible(aiDatasetEntityDTO, aiDataset);
	}

	/**
	 * 查询知识库详细信息
	 * <p>
	 * 包含基本信息和可见用户列表 支持按ID或名称查询
	 * @param dataset 查询条件（ID或名称）
	 * @return 知识库详细信息
	 */
	@Override
	public R getAiDataset(AiDatasetEntity dataset) {
		AiDatasetEntityDTO aiDatasetEntityDTO = new AiDatasetEntityDTO();
		// 查询知识库基本信息
		AiDatasetEntity aiDatasetEntity = baseMapper.selectOne(Wrappers.<AiDatasetEntity>lambdaQuery()
			.eq(Objects.nonNull(dataset.getId()), AiDatasetEntity::getId, dataset.getId())
			.eq(StrUtil.isNotBlank(dataset.getName()), AiDatasetEntity::getName, dataset.getName()), false);

		if (Objects.isNull(aiDatasetEntity)) {
			return R.ok();
		}

		BeanUtils.copyProperties(aiDatasetEntity, aiDatasetEntityDTO);

		// 根据数据集ID查询可见用户
		List<AiDatasetUserEntity> datasetUserEntityList = aiDatasetUserMapper.selectList(
				Wrappers.<AiDatasetUserEntity>lambdaQuery().eq(AiDatasetUserEntity::getDatasetId, dataset.getId()));

		if (CollUtil.isEmpty(datasetUserEntityList)) {
			return R.ok(aiDatasetEntityDTO);
		}

		// 查询并组装用户信息
		R<List<SysUser>> userListR = remoteUserService
			.getUserById(datasetUserEntityList.stream().map(AiDatasetUserEntity::getUserId).toList());
		List<AiDatasetEntityDTO.VisibleUser> visibleUserList = userListR.getData().stream().map(sysUser -> {
			AiDatasetEntityDTO.VisibleUser visibleUser = new AiDatasetEntityDTO.VisibleUser();
			visibleUser.setId(sysUser.getUserId());
			visibleUser.setName(sysUser.getName());
			visibleUser.setAvatar(sysUser.getAvatar());
			aiDatasetEntityDTO.getVisibleUsers().add(visibleUser);
			return visibleUser;
		}).toList();

		aiDatasetEntityDTO.setVisibleUsers(visibleUserList);
		return R.ok(aiDatasetEntityDTO);
	}

	/**
	 * 获取当前用户可访问的知识库列表
	 * <p>
	 * 包含公开知识库和用户私有知识库 按排序权重降序排列
	 * @return 可访问的知识库列表
	 */
	@Override
	public R listDataset() {
		List<AiDatasetEntity> datasetEntityList = baseMapper
			.selectList(Wrappers.<AiDatasetEntity>lambdaQuery().orderByDesc(AiDatasetEntity::getSortOrder));

		// 查询所有公开的知识库（不在用户关联表中的）
		List<Long> distinctDatasetId = aiDatasetUserMapper.selectDistinctDatasetId(null);
		List<Long> datasetIdList = datasetEntityList.stream()
			.filter(datasetEntity -> !distinctDatasetId.contains(datasetEntity.getId()))
			.map(AiDatasetEntity::getId)
			.toList();

		// 查询当前用户的私有知识库
		Long userId = SecurityUtils.getUser().getId();
		List<Long> userDatasetIdList = aiDatasetUserMapper.selectDistinctDatasetId(userId);

		Collection<Long> idList = CollUtil.addAll(datasetIdList, userDatasetIdList);
		if (CollUtil.isEmpty(idList)) {
			return R.ok();
		}

		return R.ok(baseMapper.selectList(Wrappers.<AiDatasetEntity>lambdaQuery()
			.in(AiDatasetEntity::getId, idList)
			.orderByDesc(AiDatasetEntity::getSortOrder)));
	}

	/**
	 * 设置知识库的可见用户
	 * <p>
	 * 清空历史权限后重新设置 支持批量添加可见用户
	 * @param aiDatasetEntityDTO 包含可见用户列表的DTO
	 * @param aiDataset 知识库实体
	 * @return 设置结果
	 */
	@NotNull
	private R<Object> setDatasetVisible(AiDatasetEntityDTO aiDatasetEntityDTO, AiDatasetEntity aiDataset) {
		// 清除历史权限记录
		aiDatasetUserMapper.delete(
				Wrappers.<AiDatasetUserEntity>lambdaQuery().eq(AiDatasetUserEntity::getDatasetId, aiDataset.getId()));
		// 如果没有设置可见用户，直接返回
		if (CollUtil.isEmpty(aiDatasetEntityDTO.getVisibleUsers())) {
			return R.ok();
		}

		List<AiDatasetUserEntity> datasetUserEntities = aiDatasetEntityDTO.getVisibleUsers()
			.stream()
			.map(visibleUser -> {
				// 创建用户权限关联记录
				AiDatasetUserEntity aiDatasetUser = new AiDatasetUserEntity();
				aiDatasetUser.setDatasetId(aiDataset.getId());
				aiDatasetUser.setUserId(visibleUser.getId());
				return aiDatasetUser;
			})
			.toList();

		// 批量插入权限记录
		aiDatasetUserMapper.insert(datasetUserEntities);
		return R.ok();
	}

}
